home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / SPOTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  9.0 KB  |  351 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <math.h>
  45. #include <GL/glut.h>
  46.  
  47. /* Some <math.h> files do not define M_PI... */
  48. #ifndef M_PI
  49. #define M_PI 3.14159265358979323846
  50. #endif
  51.  
  52. #define TWO_PI    (2*M_PI)
  53.  
  54. typedef struct lightRec {
  55.   float amb[4];
  56.   float diff[4];
  57.   float spec[4];
  58.   float pos[4];
  59.   float spotDir[3];
  60.   float spotExp;
  61.   float spotCutoff;
  62.   float atten[3];
  63.  
  64.   float trans[3];
  65.   float rot[3];
  66.   float swing[3];
  67.   float arc[3];
  68.   float arcIncr[3];
  69. } Light;
  70.  
  71. static int useSAME_AMB_SPEC = 1;
  72. /* *INDENT-OFF* */
  73. static float modelAmb[4] = {0.2, 0.2, 0.2, 1.0};
  74.  
  75. static float matAmb[4] = {0.2, 0.2, 0.2, 1.0};
  76. static float matDiff[4] = {0.8, 0.8, 0.8, 1.0};
  77. static float matSpec[4] = {0.4, 0.4, 0.4, 1.0};
  78. static float matEmission[4] = {0.0, 0.0, 0.0, 1.0};
  79. /* *INDENT-ON* */
  80.  
  81. #define NUM_LIGHTS 3
  82. static Light spots[] =
  83. {
  84.   {
  85.     {0.2, 0.0, 0.0, 1.0},  /* ambient */
  86.     {0.8, 0.0, 0.0, 1.0},  /* diffuse */
  87.     {0.4, 0.0, 0.0, 1.0},  /* specular */
  88.     {0.0, 0.0, 0.0, 1.0},  /* position */
  89.     {0.0, -1.0, 0.0},   /* direction */
  90.     20.0,
  91.     60.0,               /* exponent, cutoff */
  92.     {1.0, 0.0, 0.0},    /* attenuation */
  93.     {0.0, 1.25, 0.0},   /* translation */
  94.     {0.0, 0.0, 0.0},    /* rotation */
  95.     {20.0, 0.0, 40.0},  /* swing */
  96.     {0.0, 0.0, 0.0},    /* arc */
  97.     {TWO_PI / 70.0, 0.0, TWO_PI / 140.0}  /* arc increment */
  98.   },
  99.   {
  100.     {0.0, 0.2, 0.0, 1.0},  /* ambient */
  101.     {0.0, 0.8, 0.0, 1.0},  /* diffuse */
  102.     {0.0, 0.4, 0.0, 1.0},  /* specular */
  103.     {0.0, 0.0, 0.0, 1.0},  /* position */
  104.     {0.0, -1.0, 0.0},   /* direction */
  105.     20.0,
  106.     60.0,               /* exponent, cutoff */
  107.     {1.0, 0.0, 0.0},    /* attenuation */
  108.     {0.0, 1.25, 0.0},   /* translation */
  109.     {0.0, 0.0, 0.0},    /* rotation */
  110.     {20.0, 0.0, 40.0},  /* swing */
  111.     {0.0, 0.0, 0.0},    /* arc */
  112.     {TWO_PI / 120.0, 0.0, TWO_PI / 60.0}  /* arc increment */
  113.   },
  114.   {
  115.     {0.0, 0.0, 0.2, 1.0},  /* ambient */
  116.     {0.0, 0.0, 0.8, 1.0},  /* diffuse */
  117.     {0.0, 0.0, 0.4, 1.0},  /* specular */
  118.     {0.0, 0.0, 0.0, 1.0},  /* position */
  119.     {0.0, -1.0, 0.0},   /* direction */
  120.     20.0,
  121.     60.0,               /* exponent, cutoff */
  122.     {1.0, 0.0, 0.0},    /* attenuation */
  123.     {0.0, 1.25, 0.0},   /* translation */
  124.     {0.0, 0.0, 0.0},    /* rotation */
  125.     {20.0, 0.0, 40.0},  /* swing */
  126.     {0.0, 0.0, 0.0},    /* arc */
  127.     {TWO_PI / 50.0, 0.0, TWO_PI / 100.0}  /* arc increment */
  128.   }
  129. };
  130.  
  131. static void
  132. usage(char *name)
  133. {
  134.   printf("\n");
  135.   printf("usage: %s [options]\n", name);
  136.   printf("\n");
  137.   printf("  Options:\n");
  138.   printf("    -geometry Specify size and position WxH+X+Y\n");
  139.   printf("    -lm       Toggle lighting(SPECULAR and AMBIENT are/not same\n");
  140.   printf("\n");
  141. #ifndef EXIT_FAILURE /* should be defined by ANSI C <stdlib.h> */
  142. #define EXIT_FAILURE 1
  143. #endif
  144.   exit(EXIT_FAILURE);
  145. }
  146.  
  147. static void
  148. initLights(void)
  149. {
  150.   int k;
  151.  
  152.   for (k = 0; k < NUM_LIGHTS; ++k) {
  153.     int lt = GL_LIGHT0 + k;
  154.     Light *light = &spots[k];
  155.  
  156.     glEnable(lt);
  157.     glLightfv(lt, GL_AMBIENT, light->amb);
  158.     glLightfv(lt, GL_DIFFUSE, light->diff);
  159.  
  160.     if (useSAME_AMB_SPEC)
  161.       glLightfv(lt, GL_SPECULAR, light->amb);
  162.     else
  163.       glLightfv(lt, GL_SPECULAR, light->spec);
  164.  
  165.     glLightf(lt, GL_SPOT_EXPONENT, light->spotExp);
  166.     glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff);
  167.     glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]);
  168.     glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]);
  169.     glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]);
  170.   }
  171. }
  172.  
  173. static void
  174. aimLights(void)
  175. {
  176.   int k;
  177.  
  178.   for (k = 0; k < NUM_LIGHTS; ++k) {
  179.     Light *light = &spots[k];
  180.  
  181.     light->rot[0] = light->swing[0] * sin(light->arc[0]);
  182.     light->arc[0] += light->arcIncr[0];
  183.     if (light->arc[0] > TWO_PI)
  184.       light->arc[0] -= TWO_PI;
  185.  
  186.     light->rot[1] = light->swing[1] * sin(light->arc[1]);
  187.     light->arc[1] += light->arcIncr[1];
  188.     if (light->arc[1] > TWO_PI)
  189.       light->arc[1] -= TWO_PI;
  190.  
  191.     light->rot[2] = light->swing[2] * sin(light->arc[2]);
  192.     light->arc[2] += light->arcIncr[2];
  193.     if (light->arc[2] > TWO_PI)
  194.       light->arc[2] -= TWO_PI;
  195.   }
  196. }
  197.  
  198. static void
  199. setLights(void)
  200. {
  201.   int k;
  202.  
  203.   for (k = 0; k < NUM_LIGHTS; ++k) {
  204.     int lt = GL_LIGHT0 + k;
  205.     Light *light = &spots[k];
  206.  
  207.     glPushMatrix();
  208.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  209.     glRotatef(light->rot[0], 1, 0, 0);
  210.     glRotatef(light->rot[1], 0, 1, 0);
  211.     glRotatef(light->rot[2], 0, 0, 1);
  212.     glLightfv(lt, GL_POSITION, light->pos);
  213.     glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir);
  214.     glPopMatrix();
  215.   }
  216. }
  217.  
  218. static void
  219. drawLights(void)
  220. {
  221.   int k;
  222.  
  223.   glDisable(GL_LIGHTING);
  224.   for (k = 0; k < NUM_LIGHTS; ++k) {
  225.     Light *light = &spots[k];
  226.  
  227.     glColor4fv(light->diff);
  228.  
  229.     glPushMatrix();
  230.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  231.     glRotatef(light->rot[0], 1, 0, 0);
  232.     glRotatef(light->rot[1], 0, 1, 0);
  233.     glRotatef(light->rot[2], 0, 0, 1);
  234.     glBegin(GL_LINES);
  235.     glVertex3f(light->pos[0], light->pos[1], light->pos[2]);
  236.     glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]);
  237.     glEnd();
  238.     glPopMatrix();
  239.   }
  240.   glEnable(GL_LIGHTING);
  241. }
  242.  
  243. static void
  244. drawPlane(int w, int h)
  245. {
  246.   int i, j;
  247.   float dw = 1.0 / w;
  248.   float dh = 1.0 / h;
  249.  
  250.   glNormal3f(0.0, 0.0, 1.0);
  251.   for (j = 0; j < h; ++j) {
  252.     glBegin(GL_TRIANGLE_STRIP);
  253.     for (i = 0; i <= w; ++i) {
  254.       glVertex2f(dw * i, dh * (j + 1));
  255.       glVertex2f(dw * i, dh * j);
  256.     }
  257.     glEnd();
  258.   }
  259. }
  260.  
  261. int spin = 0;
  262.  
  263. void
  264. display(void)
  265. {
  266.   glClear(GL_COLOR_BUFFER_BIT);
  267.  
  268.   glPushMatrix();
  269.   glRotatef(spin, 0, 1, 0);
  270.  
  271.   aimLights();
  272.   setLights();
  273.  
  274.   glPushMatrix();
  275.   glRotatef(-90.0, 1, 0, 0);
  276.   glScalef(1.9, 1.9, 1.0);
  277.   glTranslatef(-0.5, -0.5, 0.0);
  278.   drawPlane(16, 16);
  279.   glPopMatrix();
  280.  
  281.   drawLights();
  282.   glPopMatrix();
  283.  
  284.   glutSwapBuffers();
  285. }
  286.  
  287. void
  288. animate(void)
  289. {
  290.   spin += 0.5;
  291.   if (spin > 360.0)
  292.     spin -= 360.0;
  293.   glutPostRedisplay();
  294. }
  295.  
  296. void
  297. visibility(int state)
  298. {
  299.   if (state == GLUT_VISIBLE) {
  300.     glutIdleFunc(animate);
  301.   } else {
  302.     glutIdleFunc(NULL);
  303.   }
  304. }
  305.  
  306. int
  307. main(int argc, char **argv)
  308. {
  309.   int i;
  310.  
  311.   glutInit(&argc, argv);
  312.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  313.   /* process commmand line args */
  314.   for (i = 1; i < argc; ++i) {
  315.     if (!strcmp("-lm", argv[i])) {
  316.       useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
  317.     } else {
  318.       usage(argv[0]);
  319.     }
  320.   }
  321.  
  322.   glutCreateWindow("GLUT spotlight swing");
  323.   glutDisplayFunc(display);
  324.   glutVisibilityFunc(visibility);
  325.  
  326.   glMatrixMode(GL_PROJECTION);
  327.   glFrustum(-1, 1, -1, 1, 2, 6);
  328.  
  329.   glMatrixMode(GL_MODELVIEW);
  330.   glTranslatef(0.0, 0.0, -3.0);
  331.   glRotatef(45.0, 1, 0, 0);
  332.  
  333.   glEnable(GL_LIGHTING);
  334.   glEnable(GL_NORMALIZE);
  335.  
  336.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
  337.   glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  338.   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  339.  
  340.   glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
  341.   glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
  342.   glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
  343.   glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
  344.   glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
  345.  
  346.   initLights();
  347.  
  348.   glutMainLoop();
  349.   return 0;             /* ANSI C requires main to return int. */
  350. }
  351.